{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 初识 Zigent：构建你的又一个智能搜索代理\n",
    "\n",
    "Zigent 是一个基于 [Agentlite](https://github.com/SalesforceAIResearch/AgentLite) 框架改进的智能代理开发框架。Agentlite 最初由 Salesforce AI Research 团队开发，是一个强大的 Agent 开发框架。Zigent 在其基础上进行了定制化改进，使其更适合特定场景的应用。\n",
    "\n",
    "在本课中，我们将学习如何使用 Zigent 框架创建一个简单但功能完整的搜索代理。这个代理能够通过 DuckDuckGo 搜索引擎查找信息并回答问题。\n",
    "\n",
    "## 环境准备\n",
    "\n",
    "首先，我们需要准备必要的环境和依赖："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Defaulting to user installation because normal site-packages is not writeable\n",
      "Looking in indexes: https://pypi.python.org/simple\n",
      "Requirement already satisfied: duckduckgo_search in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (7.1.1)\n",
      "Requirement already satisfied: zigent in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (0.0.3)\n",
      "Requirement already satisfied: click>=8.1.7 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from duckduckgo_search) (8.1.8)\n",
      "Requirement already satisfied: primp>=0.9.2 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from duckduckgo_search) (0.14.0)\n",
      "Requirement already satisfied: lxml>=5.3.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from duckduckgo_search) (5.3.0)\n",
      "Requirement already satisfied: openai==1.58.1 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (1.58.1)\n",
      "Requirement already satisfied: pydantic==2.10.4 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (2.10.4)\n",
      "Requirement already satisfied: black==24.10.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (24.10.0)\n",
      "Requirement already satisfied: numpy==2.2.1 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (2.2.1)\n",
      "Requirement already satisfied: wikipedia==1.4.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (1.4.0)\n",
      "Requirement already satisfied: openmeteo_requests==1.3.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (1.3.0)\n",
      "Requirement already satisfied: requests_cache==1.2.1 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (1.2.1)\n",
      "Requirement already satisfied: retry_requests==2.0.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (2.0.0)\n",
      "Requirement already satisfied: python-dotenv==1.0.1 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (1.0.1)\n",
      "Requirement already satisfied: streamlit==1.41.1 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zigent) (1.41.1)\n",
      "Requirement already satisfied: mypy-extensions>=0.4.3 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from black==24.10.0->zigent) (1.0.0)\n",
      "Requirement already satisfied: packaging>=22.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from black==24.10.0->zigent) (24.2)\n",
      "Requirement already satisfied: pathspec>=0.9.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from black==24.10.0->zigent) (0.12.1)\n",
      "Requirement already satisfied: platformdirs>=2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from black==24.10.0->zigent) (4.3.6)\n",
      "Requirement already satisfied: tomli>=1.1.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from black==24.10.0->zigent) (2.2.1)\n",
      "Requirement already satisfied: typing-extensions>=4.0.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from black==24.10.0->zigent) (4.12.2)\n",
      "Requirement already satisfied: anyio<5,>=3.5.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from openai==1.58.1->zigent) (4.8.0)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from openai==1.58.1->zigent) (1.9.0)\n",
      "Requirement already satisfied: httpx<1,>=0.23.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from openai==1.58.1->zigent) (0.28.1)\n",
      "Requirement already satisfied: jiter<1,>=0.4.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from openai==1.58.1->zigent) (0.8.2)\n",
      "Requirement already satisfied: sniffio in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from openai==1.58.1->zigent) (1.3.1)\n",
      "Requirement already satisfied: tqdm>4 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from openai==1.58.1->zigent) (4.67.1)\n",
      "Requirement already satisfied: openmeteo-sdk>=1.4.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from openmeteo_requests==1.3.0->zigent) (1.18.6)\n",
      "Requirement already satisfied: requests in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from openmeteo_requests==1.3.0->zigent) (2.32.3)\n",
      "Requirement already satisfied: annotated-types>=0.6.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from pydantic==2.10.4->zigent) (0.7.0)\n",
      "Requirement already satisfied: pydantic-core==2.27.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from pydantic==2.10.4->zigent) (2.27.2)\n",
      "Requirement already satisfied: attrs>=21.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from requests_cache==1.2.1->zigent) (25.1.0)\n",
      "Requirement already satisfied: cattrs>=22.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from requests_cache==1.2.1->zigent) (24.1.2)\n",
      "Requirement already satisfied: url-normalize>=1.4 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from requests_cache==1.2.1->zigent) (1.4.3)\n",
      "Requirement already satisfied: urllib3>=1.25.5 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from requests_cache==1.2.1->zigent) (2.3.0)\n",
      "Requirement already satisfied: altair<6,>=4.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from streamlit==1.41.1->zigent) (5.5.0)\n",
      "Requirement already satisfied: blinker<2,>=1.0.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from streamlit==1.41.1->zigent) (1.9.0)\n",
      "Requirement already satisfied: cachetools<6,>=4.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (5.5.1)\n",
      "Requirement already satisfied: pandas<3,>=1.4.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (2.0.3)\n",
      "Requirement already satisfied: pillow<12,>=7.1.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (11.1.0)\n",
      "Requirement already satisfied: protobuf<6,>=3.20 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (5.29.3)\n",
      "Requirement already satisfied: pyarrow>=7.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (19.0.0)\n",
      "Requirement already satisfied: rich<14,>=10.14.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (13.9.4)\n",
      "Requirement already satisfied: tenacity<10,>=8.1.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (8.3.0)\n",
      "Requirement already satisfied: toml<2,>=0.10.1 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from streamlit==1.41.1->zigent) (0.10.2)\n",
      "Requirement already satisfied: watchdog<7,>=2.1.5 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from streamlit==1.41.1->zigent) (6.0.0)\n",
      "Requirement already satisfied: gitpython!=3.1.19,<4,>=3.0.7 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (3.1.44)\n",
      "Requirement already satisfied: pydeck<1,>=0.8.0b4 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from streamlit==1.41.1->zigent) (0.9.1)\n",
      "Requirement already satisfied: tornado<7,>=6.0.3 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from streamlit==1.41.1->zigent) (6.4.2)\n",
      "Requirement already satisfied: beautifulsoup4 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from wikipedia==1.4.0->zigent) (4.13.3)\n",
      "Requirement already satisfied: colorama in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from click>=8.1.7->duckduckgo_search) (0.4.6)\n",
      "Requirement already satisfied: jinja2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from altair<6,>=4.0->streamlit==1.41.1->zigent) (3.1.5)\n",
      "Requirement already satisfied: jsonschema>=3.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from altair<6,>=4.0->streamlit==1.41.1->zigent) (4.23.0)\n",
      "Requirement already satisfied: narwhals>=1.14.2 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from altair<6,>=4.0->streamlit==1.41.1->zigent) (1.27.1)\n",
      "Requirement already satisfied: exceptiongroup>=1.0.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from anyio<5,>=3.5.0->openai==1.58.1->zigent) (1.2.2)\n",
      "Requirement already satisfied: idna>=2.8 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from anyio<5,>=3.5.0->openai==1.58.1->zigent) (3.10)\n",
      "Requirement already satisfied: gitdb<5,>=4.0.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from gitpython!=3.1.19,<4,>=3.0.7->streamlit==1.41.1->zigent) (4.0.12)\n",
      "Requirement already satisfied: certifi in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpx<1,>=0.23.0->openai==1.58.1->zigent) (2025.1.31)\n",
      "Requirement already satisfied: httpcore==1.* in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpx<1,>=0.23.0->openai==1.58.1->zigent) (1.0.7)\n",
      "Requirement already satisfied: h11<0.15,>=0.13 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpcore==1.*->httpx<1,>=0.23.0->openai==1.58.1->zigent) (0.14.0)\n",
      "Requirement already satisfied: flatbuffers==24.3.25 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from openmeteo-sdk>=1.4.0->openmeteo_requests==1.3.0->zigent) (24.3.25)\n",
      "Requirement already satisfied: python-dateutil>=2.8.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from pandas<3,>=1.4.0->streamlit==1.41.1->zigent) (2.9.0.post0)\n",
      "Requirement already satisfied: pytz>=2020.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from pandas<3,>=1.4.0->streamlit==1.41.1->zigent) (2025.1)\n",
      "Requirement already satisfied: tzdata>=2022.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from pandas<3,>=1.4.0->streamlit==1.41.1->zigent) (2025.1)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from requests->openmeteo_requests==1.3.0->zigent) (3.4.1)\n",
      "Requirement already satisfied: markdown-it-py>=2.2.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from rich<14,>=10.14.0->streamlit==1.41.1->zigent) (3.0.0)\n",
      "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from rich<14,>=10.14.0->streamlit==1.41.1->zigent) (2.19.1)\n",
      "Requirement already satisfied: six in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from url-normalize>=1.4->requests_cache==1.2.1->zigent) (1.17.0)\n",
      "Requirement already satisfied: soupsieve>1.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from beautifulsoup4->wikipedia==1.4.0->zigent) (2.6)\n",
      "Requirement already satisfied: smmap<6,>=3.0.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from gitdb<5,>=4.0.1->gitpython!=3.1.19,<4,>=3.0.7->streamlit==1.41.1->zigent) (5.0.2)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from jinja2->altair<6,>=4.0->streamlit==1.41.1->zigent) (3.0.2)\n",
      "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from jsonschema>=3.0->altair<6,>=4.0->streamlit==1.41.1->zigent) (2024.10.1)\n",
      "Requirement already satisfied: referencing>=0.28.4 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from jsonschema>=3.0->altair<6,>=4.0->streamlit==1.41.1->zigent) (0.36.2)\n",
      "Requirement already satisfied: rpds-py>=0.7.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from jsonschema>=3.0->altair<6,>=4.0->streamlit==1.41.1->zigent) (0.22.3)\n",
      "Requirement already satisfied: mdurl~=0.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from markdown-it-py>=2.2.0->rich<14,>=10.14.0->streamlit==1.41.1->zigent) (0.1.2)\n"
     ]
    }
   ],
   "source": [
    "# 建议 Python > 3.8\n",
    "!pip install duckduckgo_search zigent "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "准备大模型相关的环境，比如```api_key```和```base_url```,此处使用自塾提供的大模型服务: http://101.132.164.17:8000 。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "# 加载环境变量\n",
    "load_dotenv()\n",
    "# 从环境变量中读取api_key\n",
    "api_key = os.getenv('ZISHU_API_KEY')\n",
    "base_url = \"http://101.132.164.17:8000/v1\"\n",
    "chat_model = \"glm-4-flash\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "引入 zigent 相关的方法如Action、Agent、大模型配置等以及 duckduckgo_search ：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "from zigent.agents import ABCAgent, BaseAgent\n",
    "from zigent.llm.agent_llms import LLM\n",
    "from zigent.commons import TaskPackage\n",
    "from zigent.actions.BaseAction import BaseAction\n",
    "from duckduckgo_search import DDGS"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 配置 LLM\n",
    "\n",
    "我们需要配置大语言模型。这里使用 zigent 封装的 LLM加载和配置 LLM 服务："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我是一个人工智能助手，名为 ChatGLM，是基于清华大学 KEG 实验室和智谱 AI 公司于 2024 年共同训练的语言模型开发的。我的任务是针对用户的问题和要求提供适当的答复和支持。\n"
     ]
    }
   ],
   "source": [
    "llm = LLM(api_key=api_key, base_url=base_url, model_name=chat_model)\n",
    "response = llm.run(\"你是谁？\")\n",
    "print(response)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 创建搜索动作\n",
    "\n",
    "首先，我们需要创建一个搜索动作类，它将处理与 DuckDuckGo 的具体交互：\n",
    "需要注意的是，DuckDuckGo 可能需要科学上网。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class DuckSearchAction(BaseAction):\n",
    "    def __init__(self) -> None:\n",
    "        action_name = \"DuckDuckGo_Search\"\n",
    "        action_desc = \"Using this action to search online content.\"\n",
    "        params_doc = {\"query\": \"the search string. be simple.\"}\n",
    "        self.ddgs = DDGS()\n",
    "        super().__init__(\n",
    "            action_name=action_name, \n",
    "            action_desc=action_desc, \n",
    "            params_doc=params_doc,\n",
    "        )\n",
    "\n",
    "    def __call__(self, query):\n",
    "        results = self.ddgs.chat(query)\n",
    "        return results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个类主要做两件事：\n",
    "\n",
    "1. 初始化时配置动作的名称、描述和参数说明\n",
    "2. 通过 __call__ 方法执行实际的搜索操作\n",
    "使用示例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "“Agent”这个词在不同的领域有不同的含义。以下是一些常见的解释：\n",
      "\n",
      "1. **一般意义**：在日常用语中，agent指的是一个代理人或代表，负责代表他人进行某种活动或决策。\n",
      "\n",
      "2. **计算机科学**：在人工智能和计算机科学中，agent通常指的是一种能够自主执行任务的程序或系统。例如，智能代理（intelligent agent）可以根据环境的变化做出决策和行动。\n",
      "\n",
      "3. **商业**：在商业领域，agent可以指代中介或代理商，他们代表公司或个人进行交易或谈判。\n",
      "\n",
      "4. **生物学**：在生物学中，agent可以指代某种能够引起生物反应的物质，如病原体或药物。\n",
      "\n",
      "5. **法律**：在法律上，agent是指被授权代表他人行事的人，通常涉及合同或法律事务。\n",
      "\n",
      "具体的含义取决于上下文。如果你有特定的领域或背景，请告诉我，我可以提供更详细的信息。\n"
     ]
    }
   ],
   "source": [
    "search_action = DuckSearchAction()\n",
    "results = search_action(\"什么是 agent\")\n",
    "print(results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们将得到类似结果：\n",
    "\n",
    "\n",
    "“Agent”这个词在不同的领域有不同的含义。以下是一些常见的解释：\n",
    "\n",
    "1. **一般意义**：在日常用语中，agent指的是一个代理人或代表，负责代表他人进行某种活动或决策 。\n",
    "\n",
    "2. **计算机科学**：在人工智能和计算机科学中，agent通常指的是一种能够感知其环境并采取行动以 实现特定目标的程序或系统。例如，智能代理可以在网络上自动执行任务。\n",
    "\n",
    "3. **商业**：在商业领域，agent可以指代中介或代理商，他们代表公司或个人进行交易或谈判。     \n",
    "\n",
    "4. **生物学**：在生物学中，agent可以指代某种物质或生物体，能够引起特定的生物反应，例如病原 体。\n",
    "\n",
    "具体的含义通常取决于上下文。如果你有特定的领域或上下文，请告诉我，我可以提供更详细的信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 创建搜索代理\n",
    "\n",
    "接下来，我们创建一个继承自 BaseAgent 的搜索代理类，它需要一个大语言模型 (llm)、一组动作（默认是 DuckSearchAction）、代理名称和角色描述："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "class DuckSearchAgent(BaseAgent):\n",
    "    def __init__(\n",
    "        self,\n",
    "        llm: LLM,\n",
    "        actions: List[BaseAction] = [DuckSearchAction()],\n",
    "        manager: ABCAgent = None,\n",
    "        **kwargs\n",
    "    ):\n",
    "        name = \"duck_search_agent\"\n",
    "        role = \"You can answer questions by using duck duck go search content.\"\n",
    "        super().__init__(\n",
    "            name=name,\n",
    "            role=role,\n",
    "            llm=llm,\n",
    "            actions=actions,\n",
    "            manager=manager\n",
    "        )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 执行代理\n",
    "\n",
    "最后，我们来执行我们创建的代理：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Agent \u001b[94mduck_search_agent\u001b[0m receives the following \u001b[4mTaskPackage\u001b[0m:\n",
      "\u001b[96m[\n",
      "\tTask ID: 76af7c56-0018-49eb-a588-7b032b82aafd\n",
      "\tInstruction: what is the found date of microsoft\n",
      "]\u001b[0m\n",
      "====\u001b[94mduck_search_agent\u001b[0m starts execution on TaskPackage 76af7c56-0018-49eb-a588-7b032b82aafd====\n",
      "Agent \u001b[94mduck_search_agent\u001b[0m takes 0-step \u001b[4mAction\u001b[0m:\n",
      "\u001b[94m{\n",
      "\tname: DuckDuckGo_Search\n",
      "\tparams: {'query': 'Microsoft foundation date'}\n",
      "}\u001b[0m\n",
      "Observation: \u001b[92mMicrosoft was founded on April 4, 1975, by Bill Gates and Paul Allen.\u001b[0m\n",
      "Agent \u001b[94mduck_search_agent\u001b[0m takes 1-step \u001b[4mAction\u001b[0m:\n",
      "\u001b[94m{\n",
      "\tname: Finish\n",
      "\tparams: {'response': 'Microsoft was founded on April 4, 1975.'}\n",
      "}\u001b[0m\n",
      "Observation: \u001b[92mMicrosoft was founded on April 4, 1975.\u001b[0m\n",
      "=========\u001b[94mduck_search_agent\u001b[0m finish execution. TaskPackage[ID:76af7c56-0018-49eb-a588-7b032b82aafd] status:\n",
      "\u001b[96m[\n",
      "\tcompletion: completed\n",
      "\tanswer: Microsoft was founded on April 4, 1975.\n",
      "]\u001b[0m\n",
      "==========\n",
      "response: Microsoft was founded on April 4, 1975.\n"
     ]
    }
   ],
   "source": [
    "def do_search_agent():\n",
    "    # 创建代理实例\n",
    "    search_agent = DuckSearchAgent(llm=llm)\n",
    "\n",
    "    # 创建任务\n",
    "    task = \"what is the found date of microsoft\"\n",
    "    task_pack = TaskPackage(instruction=task)\n",
    "\n",
    "    # 执行任务并获取响应\n",
    "    response = search_agent(task_pack)\n",
    "    print(\"response:\", response)\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    do_search_agent()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "执行程序之后，理想情况下，我们将获得类似下面的日志结果：\n",
    "```\n",
    "Agent duck_search_agent receives the following TaskPackage:\n",
    "[\n",
    "        Task ID: 51c6eb6c-c544-4732-8765-982228f61d31\n",
    "        Instruction: what is the found date of microsoft\n",
    "]\n",
    "====duck_search_agent starts execution on TaskPackage 51c6eb6c-c544-4732-8765-982228f61d31====\n",
    "Agent duck_search_agent takes 0-step Action:\n",
    "{\n",
    "        name: DuckDuckGo_Search\n",
    "        params: {'query': 'Microsoft founding date'}\n",
    "}\n",
    "Observation: Microsoft was founded on April 4, 1975.\n",
    "Agent duck_search_agent takes 1-step Action:\n",
    "{\n",
    "        name: Finish\n",
    "        params: {'response': 'Microsoft was founded on April 4, 1975.'}\n",
    "}\n",
    "Observation: Microsoft was founded on April 4, 1975.\n",
    "=========duck_search_agent finish execution. TaskPackage[ID:51c6eb6c-c544-4732-8765-982228f61d31] status:\n",
    "[\n",
    "        completion: completed\n",
    "        answer: Microsoft was founded on April 4, 1975.\n",
    "]\n",
    "==========\n",
    "response: Microsoft was founded on April 4, 1975.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "如果不想通过科学上网，可以利用 ZhipuAI 的 [web_search](https://open.bigmodel.cn/dev/howuse/websearch) 实现。\n",
    "开始前我们需要安装一下 ZhipuAI SDK:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Defaulting to user installation because normal site-packages is not writeableNote: you may need to restart the kernel to use updated packages.\n",
      "\n",
      "Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple\n",
      "Requirement already satisfied: zhipuai in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (2.1.5.20250106)\n",
      "Requirement already satisfied: cachetools>=4.2.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from zhipuai) (5.5.1)\n",
      "Requirement already satisfied: httpx>=0.23.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from zhipuai) (0.28.1)\n",
      "Requirement already satisfied: pydantic<3.0,>=1.9.0 in c:\\users\\huqi\\appdata\\roaming\\python\\python310\\site-packages (from zhipuai) (2.10.4)\n",
      "Requirement already satisfied: pydantic-core>=2.14.6 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from zhipuai) (2.27.2)\n",
      "Requirement already satisfied: pyjwt<2.9.0,>=2.8.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from zhipuai) (2.8.0)\n",
      "Requirement already satisfied: anyio in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpx>=0.23.0->zhipuai) (4.8.0)\n",
      "Requirement already satisfied: certifi in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpx>=0.23.0->zhipuai) (2025.1.31)\n",
      "Requirement already satisfied: httpcore==1.* in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpx>=0.23.0->zhipuai) (1.0.7)\n",
      "Requirement already satisfied: idna in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpx>=0.23.0->zhipuai) (3.10)\n",
      "Requirement already satisfied: h11<0.15,>=0.13 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from httpcore==1.*->httpx>=0.23.0->zhipuai) (0.14.0)\n",
      "Requirement already satisfied: annotated-types>=0.6.0 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from pydantic<3.0,>=1.9.0->zhipuai) (0.7.0)\n",
      "Requirement already satisfied: typing-extensions>=4.12.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from pydantic<3.0,>=1.9.0->zhipuai) (4.12.2)\n",
      "Requirement already satisfied: exceptiongroup>=1.0.2 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from anyio->httpx>=0.23.0->zhipuai) (1.2.2)\n",
      "Requirement already satisfied: sniffio>=1.1 in c:\\programdata\\miniconda3\\envs\\dbgpt_env\\lib\\site-packages (from anyio->httpx>=0.23.0->zhipuai) (1.3.1)\n"
     ]
    }
   ],
   "source": [
    "pip install --upgrade zhipuai"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "并在 `.env` 中新增 `ZHIPU_API_KEY`并填入您的 ZhipuAI APIKey。\n",
    "和上文环境准备、配置 LLM，此处新增了 ZhipuAI SDK 的引用以及 ZHIPU_API_KEY 的配置。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import json\n",
    "import requests\n",
    "from dotenv import load_dotenv\n",
    "from typing import List\n",
    "from zigent.agents import BaseAgent, ABCAgent\n",
    "from zigent.llm.agent_llms import LLM\n",
    "from zigent.commons import TaskPackage\n",
    "from zigent.actions.BaseAction import BaseAction\n",
    "from zhipuai import ZhipuAI\n",
    "from datetime import datetime\n",
    "\n",
    "# 加载环境变量\n",
    "load_dotenv()\n",
    "api_key = os.getenv('ZISHU_API_KEY')\n",
    "base_url = \"http://101.132.164.17:8000/v1\"\n",
    "chat_model = \"Qwen2.5-72B\"\n",
    "ZHIPU_API_KEY = os.getenv('ZHIPU_API_KEY')\n",
    "\n",
    "# 配置LLM\n",
    "llm = LLM(api_key=api_key, base_url=base_url, model_name=chat_model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "定义Zhipu Web Search工具，使用智谱AI的GLM-4模型进行联网搜索，返回搜索结果的字符串。建议使用免费的 `glm-4-flash`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义Zhipu Web Search工具\n",
    "def zhipu_web_search_tool(query: str) -> str:\n",
    "    \"\"\"\n",
    "    使用智谱AI的GLM-4模型进行联网搜索，返回搜索结果的字符串。\n",
    "    \n",
    "    参数:\n",
    "    - query: 搜索关键词\n",
    "\n",
    "    返回:\n",
    "    - 搜索结果的字符串形式\n",
    "    \"\"\"\n",
    "    # 初始化客户端\n",
    "    client = ZhipuAI(api_key=ZHIPU_API_KEY)\n",
    "\n",
    "    # 获取当前日期\n",
    "    current_date = datetime.now().strftime(\"%Y-%m-%d\")\n",
    "\n",
    "    print(\"current_date:\", current_date)\n",
    "    \n",
    "    # 设置工具\n",
    "    tools = [{\n",
    "        \"type\": \"web_search\",\n",
    "        \"web_search\": {\n",
    "            \"enable\": True\n",
    "        }\n",
    "    }]\n",
    "\n",
    "    # 系统提示模板，包含时间信息\n",
    "    system_prompt = f\"\"\"你是一个具备网络访问能力的智能助手，在适当情况下，优先使用网络信息（参考信息）来回答，\n",
    "    以确保用户得到最新、准确的帮助。当前日期是 {current_date}。\"\"\"\n",
    "        \n",
    "    # 构建消息\n",
    "    messages = [\n",
    "        {\"role\": \"system\", \"content\": system_prompt},\n",
    "        {\"role\": \"user\", \"content\": query}\n",
    "    ]\n",
    "        \n",
    "    # 调用API\n",
    "    response = client.chat.completions.create(\n",
    "        model=\"glm-4-flash\",\n",
    "        messages=messages,\n",
    "        tools=tools\n",
    "    )\n",
    "    \n",
    "    # 返回结果\n",
    "    return response.choices[0].message.content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实现 ZhipuSearchAction:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ZhipuSearchAction(BaseAction):\n",
    "    def __init__(self) -> None:\n",
    "        action_name = \"Zhipu_Search\"\n",
    "        action_desc = \"Using this action to search online content.\"\n",
    "        params_doc = {\"query\": \"the search string. be simple.\"}\n",
    "        super().__init__(\n",
    "            action_name=action_name,\n",
    "            action_desc=action_desc,\n",
    "            params_doc=params_doc,\n",
    "        )\n",
    "\n",
    "    def __call__(self, query):\n",
    "        results = zhipu_web_search_tool(query)\n",
    "        return results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实现 ZhipuSearchAgent："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ZhipuSearchAgent(BaseAgent):\n",
    "    def __init__(\n",
    "        self,\n",
    "        llm: LLM,\n",
    "        actions: List[BaseAction] = [ZhipuSearchAction()],\n",
    "        manager: ABCAgent = None,\n",
    "        **kwargs\n",
    "    ):\n",
    "        name = \"zhiu_search_agent\"\n",
    "        role = \"You can answer questions by using Zhipu search content.\"\n",
    "        super().__init__(\n",
    "            name=name,\n",
    "            role=role,\n",
    "            llm=llm,\n",
    "            actions=actions,\n",
    "            manager=manager,\n",
    "        )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实现 do_search_agent 并调用，这里以 `2025年洛杉矶大火` 为例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Agent \u001b[94mzhiu_search_agent\u001b[0m receives the following \u001b[4mTaskPackage\u001b[0m:\n",
      "\u001b[96m[\n",
      "\tTask ID: 76af7c56-0018-49eb-a588-7b032b82aafd\n",
      "\tInstruction: 2025年洛杉矶大火\n",
      "]\u001b[0m\n",
      "====\u001b[94mzhiu_search_agent\u001b[0m starts execution on TaskPackage 76af7c56-0018-49eb-a588-7b032b82aafd====\n",
      "Agent \u001b[94mzhiu_search_agent\u001b[0m takes 0-step \u001b[4mAction\u001b[0m:\n",
      "\u001b[94m{\n",
      "\tname: Zhipu_Search\n",
      "\tparams: {'query': '2025年洛杉矶大火'}\n",
      "}\u001b[0m\n",
      "current_date: 2025-02-24\n",
      "Observation: \u001b[92m2025年洛杉矶大火是美国历史上最为严重的自然灾害之一。这场大火于2025年1月初在加利福尼亚州洛杉矶地区爆发，起因是太平洋帕利塞德地区的山区发生火灾。由于干燥的植被和强风（圣安娜风）的推动，火势迅速蔓延，覆盖了帕萨迪纳、圣费尔南多山谷、马里布沿海地区等多个区域。\n",
      "\n",
      "大火造成了巨大的损失，包括超过12,000公顷的土地被烧毁，数千栋建筑被摧毁，至少12000栋建筑无法居住。据报道，火灾至少导致27人死亡，近10万人流离失所。初步估计，这场大火造成的经济损失可能高达2500亿美元。\n",
      "\n",
      "这场火灾之所以如此严重，一方面是因为气候变化导致极端天气事件的频繁发生，另一方面是由于持续的干旱和高温使得植被干燥，成为了火灾的燃料。此外，圣安娜风的风力达到每小时160公里，相当于2级飓风的强度，极大地助长了火势的蔓延。\n",
      "\n",
      "这场大火不仅对洛杉矶地区造成了巨大的破坏，还引发了全球范围内的关注。专家指出，气候变化使得野火变得更加严重，未来类似的灾害可能会在更多地区发生。此外，这场大火也凸显了保险行业在面对极端天气事件时的脆弱性，可能导致一些保险公司退出市场，进而引发连锁反应，威胁全球金融体系。\u001b[0m\n",
      "Agent \u001b[94mzhiu_search_agent\u001b[0m takes 1-step \u001b[4mAction\u001b[0m:\n",
      "\u001b[94m{\n",
      "\tname: Finish\n",
      "\tparams: {'response': '2025年洛杉矶大火是美国历史上最严重的自然灾害之一，起因于2025年1月初在加州洛杉矶地区的火灾。火势迅速蔓延，导致12,000公顷土地被烧毁，数千栋建筑被摧毁，至少12000栋建筑无法居住。火灾导致27人死亡，近10万人流离失所，经济损失可能高达2500亿美元。这场灾难引发了全球关注，并突显了气候变化对极端天气事件的影响。'}\n",
      "}\u001b[0m\n",
      "Observation: \u001b[92m2025年洛杉矶大火是美国历史上最严重的自然灾害之一，起因于2025年1月初在加州洛杉矶地区的火灾。火势迅速蔓延，导致12,000公顷土地被烧毁，数千栋建筑被摧毁，至少12000栋建筑无法居住。火灾导致27人死亡，近10万人流离失所，经济损失可能高达2500亿美元。这场灾难引发了全球关注，并突显了气候变化对极端天气事件的影响。\u001b[0m\n",
      "=========\u001b[94mzhiu_search_agent\u001b[0m finish execution. TaskPackage[ID:76af7c56-0018-49eb-a588-7b032b82aafd] status:\n",
      "\u001b[96m[\n",
      "\tcompletion: completed\n",
      "\tanswer: 2025年洛杉矶大火是美国历史上最严重的自然灾害之一，起因于2025年1月初在加州洛杉矶地区的火灾。火势迅速蔓延，导致12,000公顷土地被烧毁，数千栋建筑被摧毁，至少12000栋建筑无法居住。火灾导致27人死亡，近10万人流离失所，经济损失可能高达2500亿美元。这场灾难引发了全球关注，并突显了气候变化对极端天气事件的影响。\n",
      "]\u001b[0m\n",
      "==========\n",
      "2025年洛杉矶大火是美国历史上最严重的自然灾害之一，起因于2025年1月初在加州洛杉矶地区的火灾。火势迅速蔓延，导致12,000公顷土地被烧毁，数千栋建筑被摧毁，至少12000栋建筑无法居住。火灾导致27人死亡，近10万人流离失所，经济损失可能高达2500亿美元。这场灾难引发了全球关注，并突显了气候变化对极端天气事件的影响。\n"
     ]
    }
   ],
   "source": [
    "def do_search_agent():\n",
    "    # 创建代理实例\n",
    "    search_agent = ZhipuSearchAgent(llm=llm)\n",
    "\n",
    "    # 创建任务\n",
    "    task = \"2025年洛杉矶大火\"\n",
    "    task_pack = TaskPackage(instruction=task)\n",
    "\n",
    "    # 执行任务并获取响应\n",
    "    response = search_agent(task_pack)\n",
    "    print(response)\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    do_search_agent()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "预期的返回结果类似：\n",
    "```\n",
    "Agent zhiu_search_agent receives the following TaskPackage:\n",
    "[\n",
    "        Task ID: c18ec1b9-dfdd-441b-9b62-8354f803a7a4\n",
    "        Instruction: 2025年洛杉矶大火\n",
    "]\n",
    "====zhiu_search_agent starts execution on TaskPackage c18ec1b9-dfdd-441b-9b62-8354f803a7a4====\n",
    "Agent zhiu_search_agent takes 0-step Action:\n",
    "{\n",
    "        name: Zhipu_Search\n",
    "        params: {'query': '2025年洛杉矶大火'}\n",
    "}\n",
    "current_date: 2025-01-16\n",
    "Observation: 2025年洛杉矶大火是美国历史上最为严重的自然灾害之一。这场大火始于1月7日，起火地点位于洛杉矶东北部的帕萨迪纳地区。火灾迅速蔓延，主要得益于干燥的植被和强劲的圣安娜风，风速达到每小时160公里，相当[TLDR]\n",
    "Agent zhiu_search_agent takes 1-step Action:\n",
    "{\n",
    "        name: Finish\n",
    "        params: {'response': '2025年洛杉矶大火是美国历史上最严重的自然灾害之一，始于1月7日，主要由于干燥的植被和强劲的圣安娜风导致。这场火灾烧毁了超过12,000公顷的土地，数千栋 建筑被毁，造成至少24人死亡，约18万人被迫撤离。经济损失可能达到1350亿至1500亿美元。'}\n",
    "}\n",
    "Observation: Task Completed.\n",
    "=========zhiu_search_agent finish execution. TaskPackage[ID:c18ec1b9-dfdd-441b-9b62-8354f803a7a4] status:\n",
    "[\n",
    "        completion: completed\n",
    "        answer: 2025年洛杉矶大火是美国历史上最严重的自然灾害之一，始于1月7日，主要由于干燥的植被和强劲的圣安娜风导致。这场火灾烧毁了超过12,000公顷的土地，数千栋建筑被毁，造成 至少24人死亡，约18万人被迫撤离。经济损失可能达到1350亿至1500亿美元。\n",
    "]\n",
    "==========\n",
    "2025年洛杉矶大火是美国历史上最严重的自然灾害之一，始于1月7日，主要由于干燥的植被和强劲的圣安娜风导致。这场火灾烧毁了超过12,000公顷的土地，数千栋建筑被毁，造成至少24人死亡，约18万人被迫撤离。经济损失可能达到1350亿至1500亿美元。\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "dbgpt_env",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
